﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.Build.Framework;

namespace DotNet.DevOps.Tasks.Util
{
    internal static class PropertyExtensions
    {
        internal static void ValidateNumberOfEmptyNotRequiredStringProperties<T>(this T @this, int minimumWithValue)
        {
            var properties = GetNonRequiredStringProperties(@this);

            var foundWithValue = properties.Where(prop => String.IsNullOrEmpty(prop.GetValue(@this, null) as string) == false).Count();

            if (foundWithValue < minimumWithValue)
            {
                throw new Exception(String.Format("Task was called with insuficient amount of parametera. At least {1} parameters must be set, only {0} was set.", foundWithValue, minimumWithValue));
            }
        }

        internal static Dictionary<String,String> GetStandardStringPropertyNameValuePairs<T>(this T @this)
        {
            return GetNonRequiredStringProperties(@this)
                                .Where(prop => Attribute.IsDefined(prop, typeof(StandardAttribute)) == true)
                                .Where(prop => String.IsNullOrEmpty(prop.GetValue(@this, null) as String) == false)
                                    .ToDictionary(prop => prop.Name, prop => prop.GetValue(@this,null) as String);
        }

        internal static Dictionary<String, String> GetSpecialStringPropertyNameValuePairsByName<T>(this T @this, String propertyName)
        {
            return GetSpecialStringProperties(@this)
                                .Where(prop => prop.Name == propertyName)
                                    .ToDictionary(prop => prop.Name, prop => prop.GetValue(@this, null) as String);
        }

        private static IEnumerable<PropertyInfo> GetSpecialStringProperties<T>(this T @this)
        {
            return GetNonRequiredStringProperties(@this)
                                .Where(prop => Attribute.IsDefined(prop, typeof (SpecialAttribute)) == true)
                                .ToList();
        }

        private static IEnumerable<PropertyInfo> GetNonRequiredStringProperties<T>(this T @this)
        {
            return typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                            .Where(x => x.PropertyType == typeof(String) && 
                                                        Attribute.IsDefined(x, typeof(RequiredAttribute)) == false)
                                                    .OrderBy(prop => prop.Name)
                                                    .ToList();
        }
    }
}
